Build a Linux C++ Project in a Docker Container without contaminating your system with unnecessary development files.
Building C++ Projects in Docker.
Building C++ projects in Linux can be a pain, especially if the project
maintainer does not have a good build process. Many projects need you to install
dependencies. Sometimes they even give you a bootstrap.sh
script which runs
sudo
commands to install packages. I personally hate when scripts attempt to
install packages, add things to my bashrc file, modify my PATH or any of the
sort.
To protect from these things, we’d like to create an isolated environment where you can build the project and pass the build objects back to your host system without contaminating your host with unnecessary development files.
I have created a few docker images which contain a lot of the required build essentials, plus a few extra libraries that are common. Such as Qt, CMake Conan, Ninja, etc. They are based off the ConanCenter docker images ( https://github.com/conan-io/conan-docker-tools )
The images come with the following packages:
- gcc
- Cmake, Ninja, Conan Package Manager
- Qt Development files
- OpenGL
- Vulkan (ubuntu 20.04 version only)
- Various other libraries
Here’s a quick set of commands to build the images.
cd /tmp
git clone https://github.com/GavinNL/gcc-dockerfiles
cd gcc-dockerfiles
cd bionic-gcc7
docker build -t ubuntu1804gcc:Dockerfile .
cd ../focal-gcc9
docker build -t ubuntu2004gcc:Dockerfile .
cd /tmp
rm -rf gcc-dockerfiles
There are two images, One based off Ubuntu 18.04 and the other based off Ubuntu 20.04.
The Docker Command
To use these images, simply create an empty folder where you’d like to build
your project and then execute the docker command. This will create two mounted
folders in the image, one for the build files and one for the source. The source
folder is mounted as read-only using the :ro
tag, but if you don’t need this,
you can remove it.
mkdir build
docker run --rm --it PATH_TO_BUILD_FOLDER:/conan/build PATH_TO_SOURCE:/conan/src:ro ubuntu2004gcc:Dockerfile /bin/bash
Bash Functions
I have the following two bash functions in my $HOME/.bashrc
file.
I can now quickly choose which Ubuntu platform I want to build for.
# Start a gcc7 environment using Ubuntu 18.04 to build a C++ project
#
# mkdir path/to/empty/build
# gcc7 /path/to/source/folder
#
gcc7() {
echo "Using $PWD as Build folder"
if [[ "$1" == "" ]]; then
echo "Argument 1 Needs to be the project folder"
return 1
fi
docker run --rm -it -v ${PWD}:/home/conan/build -v $(realpath ${1}):/home/conan/src:ro ubuntu1804gcc:Dockerfile /bin/bash
}
# Start a gcc9 environment using Ubuntu 20.04 to build a C++ project
#
# mkdir path/to/empty/build
# gcc9 /path/to/source/folder
#
gcc9() {
echo "Using $PWD as Build folder"
if [[ "$1" == "" ]]; then
echo "Argument 1 Needs to be the project folder"
return 1
fi
docker run --rm -it -v ${PWD}:/home/conan/build -v $(realpath ${1}):/home/conan/src:ro ubuntu2004gcc10:Dockerfile /bin/bash
}
Example
We are going to build the Easy Profiler GUI on Ubuntu 20.04
git clone https://github.com/yse/easy_profiler
cd easy_profiler
mkdir build
cd build
gcc9 ..
# we are now in the docker container
cd build
cmake ../src -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=Off
make
#exit the container
exit
If everything worked out, you should have the executable binaries in the build
folder on your host. Because the container used the same Ubuntu image, it
should be able to find the Qt libraries on your system.